﻿#region license
// Copyright (c) 2008 - 2008 Ritesh Rao
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// 
//     * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//     * Neither the name of Ayende Rahien nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

using System;
using System.IO;
using NCommon;

namespace Rhinestone.Domain
{
    /// <summary>
    /// The actual file associatd with a <see cref="Attachment"/> instance.
    /// </summary>
    public class AttachmentFile
    {
        #region fields
        private string _contentType;
        private int _contentLength;
        private byte[] _contents;
        #endregion

        #region .ctor
        /// <summary>
        /// Default Constructor.
        /// </summary>
        protected AttachmentFile() {}

        /// <summary>
        /// Overloaded Constructor.
        /// Creates a new instance of the <see cref="AttachmentFile"/> class containing contents
        /// of the specified content type and length.
        /// </summary>
        /// <param name="contentType">string. The MIME type of the content.</param>
        /// <param name="contentLength">int. The length of contents.</param>
        /// <param name="contents">byte[]. The content of the attachment file.</param>
        public AttachmentFile(string contentType, int contentLength, byte[] contents)
        {
            Guard.Against<ArgumentNullException>(string.IsNullOrEmpty(contentType),
                                                 "Expected a non-null valid string representing a MIME type for contentType");
            Guard.Against<ArgumentOutOfRangeException>(contentLength == 0, "Expecting contentLength to be greater than zero.");
            Guard.Against<ArgumentNullException>(contents == null, "Expected a non-null byte[] for contents parameter.");
            Guard.Against<ArgumentException>(contents.Length == 0, "Expected a valud non-null byte[] for contents.");

            _contentType = contentType;
            _contentLength = contentLength;
            _contents = contents;
        }

        /// <summary>
        /// Overloaded Constructor.
        /// Creates a new instance of the <see cref="AttachmentFile"/> class containing contents
        /// of the specified content type.
        /// </summary>
        /// <param name="contentType">string. The MIME type of the content.</param>
        /// <param name="contentStream">A <see cref="Stream"/> containing the contents of the attachment file.</param>
        public AttachmentFile(string contentType, Stream contentStream)
        {
            Guard.Against<ArgumentNullException>(string.IsNullOrEmpty(contentType),
                                                 "Expected a non-null valid string representing a MIME type for contentType");
            Guard.Against<ArgumentNullException>(contentStream == null, "Expected a non-null stream for contentType.");
            Guard.Against<ArgumentException>(contentStream.Length == 0, "Cannot create a AttachmentFile from a zero length stream.");

            _contentType = contentType;
            _contentLength = (int) contentStream.Length;
            _contents = new byte[_contentLength];
            contentStream.Read(_contents, 0, _contentLength);
        }
        #endregion

        #region properties
        /// <summary>
        /// Gets the MIME type that specifies the content type of the file.
        /// </summary>
        /// <value>string. The MIME type that specifies the content type of the file.</value>
        public virtual string ContentType
        {
            get { return _contentType; }
            protected set { _contentType = value; }
        }

        /// <summary>
        /// Gets the content length of the file.
        /// </summary>
        /// <value>int. The content length of the file.</value>
        public virtual int ContentLength
        {
            get { return _contentLength; }
            protected set { _contentLength = value; }
        }

        /// <summary>
        /// Gets the contents of the file.
        /// </summary>
        /// <value>byte[]. The contents of the file.</value>
        public byte[] Contents
        {
            get { return _contents; }
        }

        /// <summary>
        /// Gets a <see cref="Stream"/> that can be used to read the contents of the <see cref="AttachmentFile"/>
        /// </summary>
        /// <value>A <see cref="Stream"/> that can be used to read the contents of the <see cref="AttachmentFile"/></value>
        public Stream ContentStream
        {
            get { return new MemoryStream(_contents); }
        }
        #endregion
    }
}
